/**
 *  堆排序
 *  @param Array array 用于初始化的数组
 *  @param Function compareFun 自定义比较函数
 *  @returns {Heap}
 *  */ 
class Heap {
    constructor(array = [], compareFun = null) {
      this.queue = [];
      if (compareFun) {
        this.compareFun = compareFun;
      }
      for (let index = 0; index < array.length; index++) {
        this.push(array[index]);
      }
    }
    compareFun(node1, node2) {
      return node1 < node2;
    }
    push(node) {
      this.queue.push(node);
      this.swim();
    }
    //下沉
    sink() {
      let curIdx = 0;
      let minInd = this.getMinInd(curIdx);
      while (this.compareFun(this.queue[curIdx], this.queue[minInd])) {
        [this.queue[curIdx], this.queue[minInd]] = [
          this.queue[minInd],
          this.queue[curIdx],
        ];
        curIdx = minInd;
        minInd = this.getMinInd(curIdx);
      }
    }
    getMinInd(curIdx) {
      let leftInd = curIdx * 2 + 1;
      let rightInd = leftInd + 1;
      let minInd = leftInd;
      if (
        rightInd < this.queue.length &&
        this.compareFun(this.queue[leftInd], this.queue[rightInd])
      )
        minInd = rightInd;
      return minInd;
    }
    //上浮
    swim() {
      let curIdx = this.queue.length - 1;
      let fatherIdx = Math.floor((curIdx - 1) / 2);
      while (this.compareFun(this.queue[fatherIdx], this.queue[curIdx])) {
        [this.queue[curIdx], this.queue[fatherIdx]] = [
          this.queue[fatherIdx],
          this.queue[curIdx],
        ];
        curIdx = fatherIdx;
        fatherIdx = Math.floor((curIdx - 1) / 2);
      }
    }
    pop() {
      if (this.queue.length == 0) return null;
      if (this.queue.length == 1) return this.queue.pop();
      const top = this.queue[0];
      this.queue[0] = this.queue.pop();
      this.sink();
      return top;
    }
    front() {
      if (this.queue.length == 0) return null;
      return this.queue[0];
    }
  }
  
  exports.Heap = Heap;
  